import math

from .base import OpF1, OpF2

__all__ = [
    "OpSin",
    "OpCos",
    "OpLn",
    "OpExp",
    "OpLog",
]


class OpSin(OpF1):
    op = disp = "sin"
    lamda = lambda _, r: math.sin(r)

    def diff(self, dx):
        return OpCos(self.r) * self.r.diff(dx)


class OpCos(OpF1):
    op = disp = "cos"
    lamda = lambda _, r: math.cos(r)

    def diff(self, dx):
        return -OpSin(self.r) * self.r.diff(dx)


class OpLn(OpF1):
    op = disp = "ln"
    lamda = lambda _, r: math.log(r)

    def diff(self, dx):
        return self.r.diff(dx) / self.r


class OpExp(OpF1):
    op = disp = "exp"
    lamda = lambda _, r: math.exp(r)

    def diff(self, dx):
        return self.r.diff(dx) * math.exp(self.r)


class OpLog(OpF2):
    op = disp = "log"
    lamda = lambda _, l, r: math.log(l, r)

    def diff(self, dx):
        return self.r.diff(dx) / self.r
